home *** CD-ROM | disk | FTP | other *** search
/ Ultimate Screensaver / Ultimate Screen Savers Collection (CMS Distributing) (1996).ISO / saver3 / xwsave1 / flame.c < prev    next >
C/C++ Source or Header  |  1994-10-15  |  4KB  |  166 lines

  1. #ifndef lint
  2. static char sccsid[] = "@(#)flame.c 1.4 91/09/27 XLOCK";
  3. #endif
  4. /*-
  5.  * flame.c - recursive fractal cosmic flames.
  6.  *
  7.  * Copyright (c) 1991 by Patrick J. Naughton.
  8.  *
  9.  * See xlock.c for copying information.
  10.  *
  11.  * Revision History:
  12.  * 27-Jun-91: vary number of functions used.
  13.  * 24-Jun-91: fixed portability problem with integer mod (%).
  14.  * 06-Jun-91: Written. (received from Scott Graves, spot@cs.cmu.edu).
  15.  */
  16.  
  17. #include "xlock.h"
  18. #include <math.h>
  19.  
  20. #define MAXTOTAL    10000
  21. #define MAXBATCH    10
  22. #define MAXLEV        4
  23.  
  24. typedef struct {
  25.     double      f[2][3][MAXLEV];/* three non-homogeneous transforms */
  26.     int         max_levels;
  27.     int         cur_level;
  28.     int         snum;
  29.     int         anum;
  30.     int         width, height;
  31.     int         num_points;
  32.     int         total_points;
  33.     int         pixcol;
  34.     Window      win;
  35.     XPoint      pts[MAXBATCH];
  36. }           flamestruct;
  37.  
  38. static flamestruct flames[MAXSCREENS];
  39.  
  40. static short
  41. halfrandom(mv)
  42.     int         mv;
  43. {
  44.     static short lasthalf = 0;
  45.     unsigned long r;
  46.  
  47.     if (lasthalf) {
  48.     r = lasthalf;
  49.     lasthalf = 0;
  50.     } else {
  51.     r = random();
  52.     lasthalf = r >> 16;
  53.     }
  54.     return r % mv;
  55. }
  56.  
  57. void
  58. initflame(win)
  59.     Window      win;
  60. {
  61.     flamestruct *fs = &flames[screen];
  62.     XWindowAttributes xwa;
  63.  
  64.     XGetWindowAttributes(dsp, win, &xwa);
  65.     fs->width = xwa.width;
  66.     fs->height = xwa.height;
  67.  
  68.     fs->max_levels = batchcount;
  69.     fs->win = win;
  70.  
  71.     XSetForeground(dsp, Scr[screen].gc, BlackPixel(dsp, screen));
  72.     XFillRectangle(dsp, win, Scr[screen].gc, 0, 0, fs->width, fs->height);
  73.  
  74.     if (!mono && Scr[screen].npixels > 2) {
  75.     fs->pixcol = halfrandom(Scr[screen].npixels);
  76.     XSetForeground(dsp, Scr[screen].gc, Scr[screen].pixels[fs->pixcol]);
  77.     } else {
  78.     XSetForeground(dsp, Scr[screen].gc, WhitePixel(dsp, screen));
  79.     }
  80. }
  81.  
  82. static      Bool
  83. recurse(fs, x, y, l)
  84.     flamestruct *fs;
  85.     register double x, y;
  86.     register int l;
  87. {
  88.     int         /*xp, yp,*/ i;
  89.     double      nx, ny;
  90.  
  91.     if (l == fs->max_levels) {
  92.     fs->total_points++;
  93.     if (fs->total_points > MAXTOTAL)    /* how long each fractal runs */
  94.         return False;
  95.  
  96.     if (x > -1.0 && x < 1.0 && y > -1.0 && y < 1.0) {
  97.         /* xp = */ fs->pts[fs->num_points].x = (int) ((fs->width / 2)
  98.                             * (x + 1.0));
  99.         /* yp = */ fs->pts[fs->num_points].y = (int) ((fs->height / 2)
  100.                             * (y + 1.0));
  101.         fs->num_points++;
  102.         if (fs->num_points > MAXBATCH) {    /* point buffer size */
  103.         XDrawPoints(dsp, fs->win, Scr[screen].gc, fs->pts,
  104.                 fs->num_points, CoordModeOrigin);
  105.         fs->num_points = 0;
  106.         }
  107.     }
  108.     } else {
  109.     for (i = 0; i < fs->snum; i++) {
  110.         nx = fs->f[0][0][i] * x + fs->f[0][1][i] * y + fs->f[0][2][i];
  111.         ny = fs->f[1][0][i] * x + fs->f[1][1][i] * y + fs->f[1][2][i];
  112.         if (i < fs->anum) {
  113.         nx = sin(nx);
  114.         ny = sin(ny);
  115.         }
  116.         if (!recurse(fs, nx, ny, l + 1))
  117.         return False;
  118.     }
  119.     }
  120.     return True;
  121. }
  122.  
  123.  
  124. void
  125. drawflame(win)
  126.     Window      win;
  127. {
  128.     flamestruct *fs = &flames[screen];
  129.  
  130.     int         i, j, k;
  131.     static      alt = 0;
  132.  
  133.     if (!(fs->cur_level++ % fs->max_levels)) {
  134.     XClearWindow(dsp, fs->win);
  135.     alt = !alt;
  136.     } else {
  137.     if (Scr[screen].npixels > 2) {
  138.         XSetForeground(dsp, Scr[screen].gc,
  139.                Scr[screen].pixels[fs->pixcol]);
  140.         if (--fs->pixcol < 0)
  141.         fs->pixcol = Scr[screen].npixels - 1;
  142.     }
  143.     }
  144.  
  145.     /* number of functions */
  146.     fs->snum = 2 + (fs->cur_level % (MAXLEV - 1));
  147.  
  148.     /* how many of them are of alternate form */
  149.     if (alt)
  150.     fs->anum = 0;
  151.     else
  152.     fs->anum = halfrandom(fs->snum) + 2;
  153.  
  154.     /* 6 coefs per function */
  155.     for (k = 0; k < fs->snum; k++) {
  156.     for (i = 0; i < 2; i++)
  157.         for (j = 0; j < 3; j++)
  158.         fs->f[i][j][k] = ((double) (random() & 1023) / 512.0 - 1.0);
  159.     }
  160.     fs->num_points = 0;
  161.     fs->total_points = 0;
  162.     (void) recurse(fs, 0.0, 0.0, 0);
  163.     XDrawPoints(dsp, win, Scr[screen].gc,
  164.         fs->pts, fs->num_points, CoordModeOrigin);
  165. }
  166.